﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using RemoteTranslation.AssistentApplication.Services;
using System.Windows.Input;
using YasharEl.Infrastructure.PresentationModel.MVVM;
using YasharEl.Infrastructure.PresentationModel.Commanding;
using System.Collections.ObjectModel;
using YasharEl.Infrastructure.PresentationModel.Services;

namespace RemoteTranslator.AssistentApplication.Plugins.ViewModels
{
    [ExportViewModel("MainViewModel")]
    [PartCreationPolicy(System.ComponentModel.Composition.CreationPolicy.NonShared)]
    public class MainViewModel : BaseViewModel
    {
        #region Fields

        private ITranslatorAssistent _translatorAssistentService;
        private IMessageBoxService _messageBoxService;

        private VideoScreenViewModel _videoScreenViewModel;
        private HeadphonesScreenViewModel _headphonesScreenViewModel;
        private MicrophoneScreenViewModel _microphoneScreenViewModel;

        private string _serverStatus = "Disconnected";

        private bool _isConnected = false;

        #endregion

        #region Constructors

        [ImportingConstructor]
        public MainViewModel(ITranslatorAssistent translatorAssistentService/*, IMessageBoxService messageBoxService*/)
        {
            _translatorAssistentService = translatorAssistentService;
            //_messageBoxService = messageBoxService;
            VideoScreenViewModel = new VideoScreenViewModel();
            HeadphonesScreenViewModel = new HeadphonesScreenViewModel();
            MicrophoneScreenViewModel = new MicrophoneScreenViewModel();
        }

        #endregion

        #region Commands

        public ICommand ConnectCommand
        {
            get
            {
                return new RelayCommand(ConnectExecute, CanConnectExecute);
            }
        }

        public ICommand DisconnectCommand
        {
            get
            {
                return new RelayCommand(DisconnectExecute, CanDisconnectExecute);
            }
        }

        #endregion

        #region Commands CanExecute and Execute Methods

        protected virtual bool CanConnectExecute()
        {
            return !_translatorAssistentService.ConnectedServer.IsConnected;
        }

        protected virtual void ConnectExecute()
        {
            _translatorAssistentService.Connect();
            IsConnected = _translatorAssistentService.ConnectedServer.IsConnected;
            if (_translatorAssistentService.ConnectedServer.IsConnected)
            {
                ServerStatus = string.Format(
                    "Connected to {0} in tcp port {1}.", 
                        _translatorAssistentService.ConnectedServer.HostAddress, 
                        _translatorAssistentService.ConnectedServer.TcpPort);
                HeadphonesScreenViewModel.CurrentInputAudioChannel = null;
                HeadphonesScreenViewModel.InputAudioChannels = new ObservableCollection<ChannelViewModel>();
                _translatorAssistentService.ConnectedServer.InputAudioChannels.ForEach(
                    delegate(ChannelInformation channelInformation)
                    {
                        ChannelViewModel channelViewModel = new ChannelViewModel();
                        channelViewModel.ChannelName = channelInformation.Name;
                        HeadphonesScreenViewModel.InputAudioChannels.Add(channelViewModel);
                    });

                MicrophoneScreenViewModel.CurrentOutputAudioChannel = null;
                MicrophoneScreenViewModel.OutputAudioChannels = new ObservableCollection<ChannelViewModel>();
                _translatorAssistentService.ConnectedServer.OutputAudioChannels.ForEach(
                    delegate(ChannelInformation channelInformation)
                    {
                        ChannelViewModel channelViewModel = new ChannelViewModel();
                        channelViewModel.ChannelName = channelInformation.Name;
                        MicrophoneScreenViewModel.OutputAudioChannels.Add(channelViewModel);
                    });
            }
            else
            {
                ServerStatus = string.Format(
                "Failed to connected to {0} in tcp port {1}.",
                    _translatorAssistentService.ConnectedServer.HostAddress,
                    _translatorAssistentService.ConnectedServer.TcpPort);
                HeadphonesScreenViewModel.CurrentInputAudioChannel = null;
                HeadphonesScreenViewModel.InputAudioChannels = new ObservableCollection<ChannelViewModel>();

                MicrophoneScreenViewModel.CurrentOutputAudioChannel = null;
                MicrophoneScreenViewModel.OutputAudioChannels = new ObservableCollection<ChannelViewModel>();
            }
        }

        protected virtual bool CanDisconnectExecute()
        {
            return _translatorAssistentService.ConnectedServer.IsConnected;
        }

        protected virtual void DisconnectExecute()
        {
            _translatorAssistentService.Disconnect();
            
            IsConnected = false;

            ServerStatus = "Disconnected";

            HeadphonesScreenViewModel.CurrentInputAudioChannel = null;
            HeadphonesScreenViewModel.InputAudioChannels = new ObservableCollection<ChannelViewModel>();

            MicrophoneScreenViewModel.CurrentOutputAudioChannel = null;
            MicrophoneScreenViewModel.OutputAudioChannels = new ObservableCollection<ChannelViewModel>();            
        }

        #endregion

        #region ViewModels

        public VideoScreenViewModel VideoScreenViewModel
        {
            get
            {
                return _videoScreenViewModel;
            }
            protected set
            {
                _videoScreenViewModel = value;
                RaisePropertyChanged("VideoScreenViewModel");
            }
        }

        public HeadphonesScreenViewModel HeadphonesScreenViewModel
        {
            get
            {
                return _headphonesScreenViewModel;
            }
            protected set
            {
                _headphonesScreenViewModel = value;
                RaisePropertyChanged("HeadphonesScreenViewModel");
            }
        }

        public MicrophoneScreenViewModel MicrophoneScreenViewModel
        {
            get
            {
                return _microphoneScreenViewModel;
            }
            protected set
            {
                _microphoneScreenViewModel = value;
                RaisePropertyChanged("MicrophoneScreenViewModel");
            }
        }

        #endregion

        #region Properties

        public string ServerStatus
        {
            get
            {
                return _serverStatus;
            }
            protected set
            {
                _serverStatus = value;
                RaisePropertyChanged("ServerStatus");
            }
        }

        public bool IsConnected
        {
            get { return _isConnected; }
            set
            {
                _isConnected = value;
                RaisePropertyChanged("IsConnected");
            }
        }

        #endregion
    }
}
